package com.xiaohu.gen;

import com.xiaohu.entity.Columns;
import com.xiaohu.entity.Table;
import lombok.extern.slf4j.Slf4j;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.springframework.util.StringUtils;

import java.io.File;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * Velocity 工具类
 */
@Slf4j
public class VelocityUtils {

    private static final String JAVA = ".java";

    /**
     * 初始化Velocity
     */
    public static void initVelocity()
    {
        Properties p = new Properties();
        try {
            // 加载classpath目录下的vm文件
            p.setProperty("resource.loader .file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
            // 定义字符集
            p.setProperty(Velocity.INPUT_ENCODING, "UTF-8");
            // 初始化Velocity引擎，指定配置Properties
            Velocity.init(p);
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取Velocity模板
     */
    public static List<String> initVelocityTemplate() {
        List<String> template = new ArrayList<>();
        template.add("X-GenCode/src/main/resources/vm/do.java.vm");
        template.add("X-GenCode/src/main/resources/vm/controller.java.vm");
        template.add("X-GenCode/src/main/resources/vm/mapper.java.vm");
        template.add("X-GenCode/src/main/resources/vm/service.java.vm");
        template.add("X-GenCode/src/main/resources/vm/serviceImpl.java.vm");
        return template;
    }

    /**
     * 设置模板变量
     */
    public static VelocityContext getVelocityContext(Table table) {
        VelocityContext velocityContext = new VelocityContext();
        velocityContext.put("packageName", table.getPackagePath());
        velocityContext.put("functionName", table.getTableComment());
        velocityContext.put("tableName", table.getTableName());
        // TODO
        velocityContext.put("author", "xiaohu");
        velocityContext.put("datetime", LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        velocityContext.put("ClassName", humpTransition(table.getTableName()));
        velocityContext.put("columns", table.getColumnsList());
        return velocityContext;
    }

    /**
     * 数据库表名转换成驼峰
     * @param str 数据库表名
     * @return JAVA的驼峰风格类名
     */
    public static String humpTransition(String str) {
        if (str.length() > 0) {
            // 首字母大写
            String s = str.substring(0, 1).toUpperCase() + str.substring(1);
            // 替换'_'(下划线)
            return underlineTransition(s);
        }else {
            return "Table";
        }
    }

    /**
     * 将字符串中的'_'(下划线)后面的一个字母替换成大写字母
     * @param str 要转换的字符串
     * @return 下划线转换成的字符串
     */
    public static String underlineTransition(String str) {
        if (str.indexOf('_') == -1) {
            return str;
        }
        int i = str.indexOf('_');
        // 截取下划线之前的内容
        String upperCase = str.substring(0, i);
        // 获取下划线后面那个字母
        String up = str.substring(i+1, i+2).toUpperCase();
        String back = str.substring(i+2);
        String newStr = upperCase + up + back;
        return underlineTransition(newStr);
    }

    /**
     * 类属性以及类名转换
     * @param columns 表结构数组
     * @return 转换结构后的表结构
     */
    public static List<Columns> propertyTransition(List<Columns> columns) {
        columns.forEach(column -> {
            // 存储老字段名
            column.setDbFieldName(column.getColumnName());
            // 转换属性名
            column.setColumnName(humpTransition(column.getColumnName()));
            // 转换数据类型
            switch (column.getDataType()) {
                case "varchar":
                case "json":
                case "TEXT":
                case "char":
                    column.setDataType("String"); break;
                case "bigint": column.setDataType("Long"); break;
                case "datetime": column.setDataType("Date"); break;
                case "float": column.setDataType("Float"); break;
                case "decimal":
                case "numeric":
                    column.setDataType("BigDecimal"); break;
                case "boolean": column.setDataType("Boolean"); break;
            }
        });
        return columns;
    }

    /**
     * 在生成文件的时候设置文件名字
     * @param template 模板名称
     * @param table 表结构对象
     * @return FileName
     */
    public static String getFileName(String template, Table table) {
        String fileName = "";
        if (template.contains("do.java.vm")) {
            fileName = table.getTableName() + JAVA;
        }
        if (template.contains("controller.java.vm")) {
            fileName = table.getTableName() + "Controller" + JAVA ;
        }
        if (template.contains("mapper.java.vm")) {
            fileName = table.getTableName() + "Mapper" + JAVA ;
        }
        if (template.contains("service.java.vm")) {
            fileName = 'I' + table.getTableName() + "Service" + JAVA ;
        }
        if (template.contains("serviceImpl.java.vm")) {
            fileName = table.getTableName() + "ServiceImpl" + JAVA ;
        }
        return fileName;
    }

    /**
     * 获取当前系统的桌面目录
     * @return 桌面路径
     */
    public static String getDesktopPath() {
        String osName = System.getProperty("os.name").toLowerCase();
        log.info("系统" + osName);
        if (osName.contains("win")) {
            // Windows系统
            log.info("路径" + System.getenv("USERPROFILE") + File.separator + "Desktop");
            return System.getenv("USERPROFILE") + File.separator + "Desktop";
        } else if (osName.contains("mac")) {
            // macOS系统
            return System.getProperty("user.home") + File.separator + "Desktop";
        } else if (osName.contains("nux") || osName.contains("aix")) {
            // Linux/Unix/AIX系统
            return System.getProperty("user.home") + File.separator + "Desktop";
        }
        // 默认返回用户家目录（可能不是桌面，但作为一个回退选项）
        return System.getProperty("user.home");
    }
}
